//! Redis基础命令兼容性集成测试
//! 
//! 测试Redis-rs2与标准Redis协议的兼容性：
//! - 启动真实的Redis-rs2服务器
//! - 使用Redis客户端连接测试
//! - 验证命令执行结果与标准Redis一致

use redis::{Client, Commands, Connection};
use crate::common::*;
use std::time::Duration;

mod basic_string_commands_integration {
    use super::*;
    
    #[tokio::test]
    async fn test_ping_command_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8000);
        
        // 启动测试服务器
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        // 等待服务器就绪
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        // 创建Redis客户端连接
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        // 执行PING命令
        let result: String = conn.cmd("PING").query()
            .expect("PING command failed");
        
        assert_eq!(result, "PONG");
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
    
    #[tokio::test]
    async fn test_set_get_commands_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8010);
        
        // 启动测试服务器
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        // 创建Redis客户端连接
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        // 生成测试数据
        let generator = TestDataGenerator::new();
        let (key, value) = generator.generate_random_kvp(10, 20);
        
        // 执行SET命令
        let set_result: String = conn.set(&key, &value)
            .expect("SET command failed");
        assert_eq!(set_result, "OK");
        
        // 执行GET命令
        let get_result: String = conn.get(&key)
            .expect("GET command failed");
        assert_eq!(get_result, value);
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
    
    #[tokio::test]
    async fn test_exists_and_del_commands_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8020);
        
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        let key = generate_test_key("exists_test");
        let value = "test_value";
        
        // 测试键不存在时的EXISTS
        let exists_before: i32 = conn.exists(&key)
            .expect("EXISTS command failed");
        assert_eq!(exists_before, 0);
        
        // 设置键值
        let _: () = conn.set(&key, value)
            .expect("SET command failed");
        
        // 测试键存在时的EXISTS
        let exists_after: i32 = conn.exists(&key)
            .expect("EXISTS command failed");
        assert_eq!(exists_after, 1);
        
        // 删除键
        let del_result: i32 = conn.del(&key)
            .expect("DEL command failed");
        assert_eq!(del_result, 1);
        
        // 验证键已被删除
        let exists_final: i32 = conn.exists(&key)
            .expect("EXISTS command failed");
        assert_eq!(exists_final, 0);
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
}

mod numeric_commands_integration {
    use super::*;
    
    #[tokio::test]
    async fn test_incr_commands_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8030);
        
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        let counter_key = generate_test_key("counter");
        
        // 测试INCR命令（从不存在开始）
        let incr_result1: i32 = conn.incr(&counter_key, 1)
            .expect("INCR command failed");
        assert_eq!(incr_result1, 1);
        
        // 再次执行INCR
        let incr_result2: i32 = conn.incr(&counter_key, 1)
            .expect("INCR command failed");
        assert_eq!(incr_result2, 2);
        
        // 测试INCRBY命令
        let incrby_result: i32 = conn.incr(&counter_key, 5)
            .expect("INCRBY command failed");
        assert_eq!(incrby_result, 7);
        
        // 验证最终值
        let final_value: i32 = conn.get(&counter_key)
            .expect("GET command failed");
        assert_eq!(final_value, 7);
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
}

mod batch_operations_integration {
    use super::*;
    
    #[tokio::test]
    async fn test_batch_set_get_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8040);
        
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        // 生成批量测试数据
        let generator = TestDataGenerator::new();
        let test_count = 50;
        let mut test_data = Vec::new();
        
        // 生成测试键值对
        for i in 0..test_count {
            let key = format!("batch_key_{}", i);
            let value = format!("batch_value_{}", i);
            test_data.push((key, value));
        }
        
        // 批量SET操作
        for (key, value) in &test_data {
            let result: String = conn.set(key, value)
                .expect("SET command failed");
            assert_eq!(result, "OK");
        }
        
        // 批量GET操作并验证
        for (key, expected_value) in &test_data {
            let actual_value: String = conn.get(key)
                .expect("GET command failed");
            assert_eq!(actual_value, *expected_value);
        }
        
        // 批量删除
        let keys: Vec<&String> = test_data.iter().map(|(k, _)| k).collect();
        let del_count: i32 = conn.del(&keys)
            .expect("DEL command failed");
        assert_eq!(del_count, test_count);
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
}

mod concurrent_operations_integration {
    use super::*;
    use std::sync::Arc;
    use tokio::sync::Barrier;
    
    #[tokio::test]
    async fn test_concurrent_clients_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8050);
        
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        let server_address = server.address();
        let client_count = 10;
        let operations_per_client = 20;
        
        // 创建同步屏障，确保所有客户端同时开始
        let barrier = Arc::new(Barrier::new(client_count));
        let mut handles = vec![];
        
        for client_id in 0..client_count {
            let address = server_address.clone();
            let barrier_clone = barrier.clone();
            
            let handle = tokio::spawn(async move {
                // 创建客户端连接
                let client = Client::open(format!("redis://{}", address))
                    .expect("Failed to create Redis client");
                
                let mut conn = client.get_connection()
                    .expect("Failed to connect to Redis server");
                
                // 等待所有客户端就绪
                barrier_clone.wait().await;
                
                // 执行操作
                for op_id in 0..operations_per_client {
                    let key = format!("concurrent_key_{}_{}", client_id, op_id);
                    let value = format!("concurrent_value_{}_{}", client_id, op_id);
                    
                    // SET操作
                    let set_result: String = conn.set(&key, &value)
                        .expect("SET command failed");
                    assert_eq!(set_result, "OK");
                    
                    // GET操作验证
                    let get_result: String = conn.get(&key)
                        .expect("GET command failed");
                    assert_eq!(get_result, value);
                    
                    // 短暂延迟以模拟真实场景
                    tokio::time::sleep(Duration::from_millis(1)).await;
                }
                
                client_id
            });
            
            handles.push(handle);
        }
        
        // 等待所有客户端完成
        for handle in handles {
            let client_id = handle.await.expect("Client task failed");
            println!("Client {} completed", client_id);
        }
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
}

mod error_handling_integration {
    use super::*;
    
    #[tokio::test]
    async fn test_error_responses_integration() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8060);
        
        let server = server_manager.create_simple_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        // 测试未知命令（如果Redis-rs2支持错误响应）
        let result = conn.cmd("UNKNOWN_COMMAND").query::<String>();
        assert!(result.is_err(), "Expected error for unknown command");
        
        // 测试参数不足的命令
        let result = conn.cmd("SET").arg("only_key").query::<String>();
        assert!(result.is_err(), "Expected error for insufficient arguments");
        
        // 测试对非数字键执行数字操作
        let text_key = generate_test_key("text_key");
        let _: () = conn.set(&text_key, "not_a_number")
            .expect("SET command failed");
        
        let result = conn.incr(&text_key, 1);
        assert!(result.is_err(), "Expected error for INCR on non-numeric value");
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
}

// 性能基准测试
mod performance_integration {
    use super::*;
    
    #[tokio::test]
    async fn test_throughput_benchmark() {
        let env = TestEnvironment::new();
        let mut server_manager = TestServerManager::new(8070);
        
        let server = server_manager.create_optimized_server().await
            .expect("Failed to start test server");
        
        tokio::time::sleep(Duration::from_millis(100)).await;
        
        let client = Client::open(format!("redis://{}", server.address()))
            .expect("Failed to create Redis client");
        
        let mut conn = client.get_connection()
            .expect("Failed to connect to Redis server");
        
        let operation_count = 1000;
        let start_time = std::time::Instant::now();
        
        // 执行大量SET操作
        for i in 0..operation_count {
            let key = format!("perf_key_{}", i);
            let value = format!("perf_value_{}", i);
            
            let _: String = conn.set(&key, &value)
                .expect("SET command failed");
        }
        
        let elapsed = start_time.elapsed();
        let ops_per_second = operation_count as f64 / elapsed.as_secs_f64();
        
        println!("Throughput: {:.2} ops/sec", ops_per_second);
        
        // 断言最小性能要求（比如每秒1000次操作）
        assert!(ops_per_second > 1000.0, "Performance below threshold: {:.2} ops/sec", ops_per_second);
        
        // 清理
        server_manager.stop_all().await.expect("Failed to stop servers");
        env.cleanup().await;
    }
}

// 注意：这些集成测试需要：
// 1. 实际可运行的Redis-rs2服务器二进制文件
// 2. 正确的服务器启动参数
// 3. 服务器支持的命令集
// 4. 正确的错误处理机制

// 可选的测试配置：
#[cfg(test)]
mod test_config {
    // 测试环境配置
    pub const TEST_TIMEOUT_MS: u64 = 30000; // 30秒超时
    pub const SERVER_START_DELAY_MS: u64 = 1000; // 服务器启动延迟
    pub const MIN_PERFORMANCE_OPS_PER_SEC: f64 = 1000.0; // 最小性能要求
}